#include "Players.h"
#include "Player.h"
#include "Color.h"
#include "Configuration.h"
#include <cstddef>

Players::Players()
{
}

Players::~Players()
{
    players.clear();
}

void Players::add(int playerId, std::string playerName)
{
    Colors usedColors = getUsedColors();
    Color color = Configuration::getFirstUnusedColor(usedColors);
    PlayerPtr player(new Player(playerId, playerName, color));
    players[playerId] = player;
}

void Players::remove(int playerId)
{
    players.erase(playerId);
}

PlayerPtr Players::getPlayer(int playerId)
{
    if (players.find(playerId) != players.end())
    {
        return players[playerId];
    }
    return PlayerPtr();
}

size_t Players::getNumberOfPlayers()
{
    return players.size();
}

size_t Players::getNumberOfReadyPlayers()
{
    size_t result = 0;
    for (PlayerMap::iterator it = players.begin(); it != players.end(); ++it)
    {
        if (it->second->isReady())
        {
            result++;
        }
    }
    return result;
}

PlayerIds Players::getPlayerIds()
{
    PlayerIds ids;
    for (PlayerMap::iterator it = players.begin(); it != players.end(); ++it)
    {
        ids.push_back(it->first);
    }
    return ids;
}

Color Players::getPlayerColor(int playerId)
{
    return getPlayer(playerId)->getColor();
}

Position Players::getPlayerPosition(int playerId, unsigned int widthOfWell)
{
    float space = widthOfWell / players.size();
    for (PlayerMap::iterator it = players.begin(); it != players.end(); ++it)
    {
        if (it->first == playerId)
        {
            int pos = std::distance(players.begin(), it);
            return Position(int(space/2 - 2 + pos * space) , -2);
        }
    }
    return Position(0, 0);
}

Colors Players::getUsedColors()
{
    Colors colors;
    for (PlayerMap::iterator it = players.begin(); it != players.end(); ++it)
    {
        colors.push_back(it->second->getColor());
    }
    return colors;
}
